#ifndef KNODE_H
#define KNODE_H

#include "LocalRegression.h"
//#define Observation double*
//#define Observation_type double 


class KDTree; 
class KNode; 



class KRect
{
public:
	KRect(); 
	KRect(int _dim,double_range_t* r); 
	~KRect(); 

	void setBox(int _dim, double_range_t* r); 
	void setBox(int _dim, double* _mins, double* _maxs); 
	void reset();					//destroy the box
	bool isValid();					//is the box initialized
	void split(KRect* lhs, KRect* rhs, int dimIndex, double splitVal); 
	void _computeSize(); 

	int dim; //dimension of this rect
	double* mins; //mins of each dimension
	double* maxs; //max of each dimension
	double size; //diameter of this rect
	double size_normalized; //size normalized to 1
	static double* widths; //this is the width of each dimension(to compute normalized width of each box)

};

class KNode
{
public:
	KNode(void);
	KNode(KDTree* t,KNode* p,  KRect* r); 
	~KNode(void);
	void init(); 

	void clearData();
	void addPointsToCurrentStructure(list<KData>& l);
	void addPoint(KData& pt); 
	void addPoints(list<KData>& pts); 
	bool isLeaf(){return splitDirection==-1; } 
	void split();		//find a suitable direction and split this cell according to that dimension
	double size();		//returns the largetst difference between max and min in a dimension
	void examineNode();
	int getSplitDimension(); 
	void splitData(list<KData> l, list<KData>& l1, list<KData>& l2, int splitDim); 
	bool predict(Observation pt, double& d); 

	void createRandomPoints(list<KData>& l, int sampleNumber); 
	void createLocalSolver(); 

	int getNumberOfNodes(); 
	int		id;			//unique id of this node
	KRect* box;			//what does this node cover
	KNode* left;		//left child
	KNode* right;		//right child
	//bool	isKnown;	//is this node known?
	double getKnownness(); 
	double getPublicKnownness(Observation st); 

	list<KData> points; //data in this cell
	int			psize; //number of samples in this cell
	
	int splitDirection;	//what direction do we split(if -1, this is a leaf node)
	double splitValue; //what is the splitting condition 

	KDTree* m_tree;		//link to the tree that owns this node
	KNode* parent; 

//	LinearSolver* solver; 
	LocalRegression* solver; 

};

#endif
